package com.unibeta.cloudtest.mesher.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.ExecuteException;
import org.apache.commons.exec.ExecuteWatchdog;
import org.apache.commons.exec.PumpStreamHandler;

import com.unibeta.vrules.tools.CommonSyntaxs;

public class CmdUtils {

	private static long timeout = 1000 * 60 * 10; // 10 minutes
	private static final String DEFAULT_CHARSET = "GBK";

	/**
	 * 执行指定命令
	 * 
	 * @param command 命令
	 * @return 0 success, 1 failed.
	 * @throws IOException 失败时抛出异常，由调用者捕获处理
	 */
	public static String exec(String command) throws IOException {
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		
		exec(command,out);

		return out.toString(DEFAULT_CHARSET);
	}
	
	/**
	 * timeunit is milliseconds
	 * @param seconds
	 */
	public static void setTimeout(long milliseconds) {
		timeout = milliseconds;
	}
	
	/**
	 * execute given command, combined to output stream.
	 * @param command
	 * @param out
	 * @return 0 success, 1 failed
	 * @throws ExecuteException
	 * @throws IOException
	 */
	public static int exec(String command, OutputStream out) throws ExecuteException, IOException {
		return exec(command,out,timeout);
	}

	/**
	 * 执行指定命令，输出结果到指定输出流中
	 * 
	 * @param command 命令
	 * @param out     执行结果输出流
	 * @return 执行结果状态码：执行成功返回0
	 * @throws ExecuteException 失败时抛出异常，由调用者捕获处理
	 * @throws IOException      失败时抛出异常，由调用者捕获处理
	 */
	public static int exec(String command, OutputStream out,long timeout) throws ExecuteException, IOException {
		
		CommandLine commandLine = CommandLine.parse(command);
		PumpStreamHandler pumpStreamHandler = null;
		
		if (null == out) {
			pumpStreamHandler = new PumpStreamHandler();
		} else {
			pumpStreamHandler = new PumpStreamHandler(out);
		}

		ExecuteWatchdog watchdog = new ExecuteWatchdog(timeout);

		DefaultExecutor executor = new DefaultExecutor();
		executor.setStreamHandler(pumpStreamHandler);
		executor.setWatchdog(watchdog);

		long start = System.currentTimeMillis();
		int exitCode = executor.execute(commandLine);
		double took  = (System.currentTimeMillis()-start)/1000.00;
		
		if (exitCode == 0) {
			CommonSyntaxs.println("exec '" + command + "' success in " + took+ "s");
		} else {
			CommonSyntaxs.println("exec '" + command + "' failed in " + took+ "s");
		}
		
		return exitCode;
	}
}
